package com.tsq.push.provider.service.impl;

import cn.hutool.core.date.DateUtil;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.push.model.v20160801.*;
import com.aliyuncs.utils.ParameterHelper;
import com.tsq.common.model.ResponseData;
import com.tsq.push.api.dto.*;
import com.tsq.push.provider.builder.PushBuilder;
import com.tsq.push.provider.service.PushService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class PushServiceImpl implements PushService {

    @Autowired
    private DefaultAcsClient sign;

    public ResponseData<PushResponse> pushTo(PushDTO pushDTO) {
        PushRequest android = PushBuilder.one()
                .buildWithDTO(pushDTO);
        try {
            return ResponseData.success(sign.getAcsResponse(android));
        } catch (ClientException e) {
            log.info("context", e);
            return ResponseData.error("请求失败！Code：" + e.getErrCode() + ",Msg：" + e.getErrMsg());
        }
    }

    public ResponseData<PushResponse> pushTo(PushRequest pushRequest) {
        try {
            return ResponseData.success(sign.getAcsResponse(pushRequest));
        } catch (ClientException e) {
            log.info("context", e);
            return ResponseData.error("请求失败！Code：" + e.getErrCode() + ",Msg：" + e.getErrMsg());
        }
    }

    public ResponseData<MassPushResponse> pushMass(MassPushRequest massPushRequest) {
        try {
            return ResponseData.success(sign.getAcsResponse(massPushRequest));
        } catch (ClientException e) {
            log.info("context", e);
            return ResponseData.error("请求失败！Code：" + e.getErrCode() + ",Msg：" + e.getErrMsg());
        }
    }


    public ResponseData<PushResponse> pushMessageTo(PushMessageToDTO pushMessageToDTO) {
        PushRequest pushRequest = new PushRequest();
        String action = pushMessageToDTO.getAction();
        if ("PushMessageToiOS".equals(action)) {
            pushRequest.setDeviceType("iOS");
            pushRequest.setPushType("MESSAGE");
        }
        if ("PushMessageToAndroid".equals(action)) {
            pushRequest.setDeviceType("ANDROID");
            pushRequest.setPushType("MESSAGE");
        }
        if ("PushNoticeToiOS".equals(action)) {
            pushRequest.setDeviceType("iOS");
            pushRequest.setPushType("NOTICE");
        }
        if ("PushNoticeToAndroid".equals(action)) {
            pushRequest.setDeviceType("ANDROID");
            pushRequest.setPushType("NOTICE");
        }
        // 推送目标
        pushRequest.setAppKey(pushMessageToDTO.getAppKey());
        pushRequest.setTarget(pushMessageToDTO.getTarget());
        pushRequest.setTargetValue(pushMessageToDTO.getTargetValue());

        // 推送配置
        pushRequest.setTitle(pushMessageToDTO.getTitle());// 消息的标题
        pushRequest.setBody(pushMessageToDTO.getBody()); // 消息的内容

//        DefaultAcsClient client =signConfig.sign();
        if (null != pushMessageToDTO.getPushDate()) {
            pushRequest = timing(pushRequest, pushMessageToDTO.getPushDate());
        }
        PushResponse pushResponse = null;
        try {
            pushResponse = sign.getAcsResponse(pushRequest);
        } catch (ClientException e) {
            log.info("context", e);
            return ResponseData.error("请求失败！Code：" + e.getErrCode() + ",Msg：" + e.getErrMsg());
        }
        return ResponseData.success(pushResponse);
    }

    @Override
    public ResponseData<PushResponse> pushAdvanced(PushAdvancedDTO pushAdvancedDTO) {
        PushRequest pushRequest = new PushRequest();
        pushRequest.setActionName("Push");
        pushRequest.setAppKey(pushAdvancedDTO.getAppKey());
        pushRequest.setBody(pushAdvancedDTO.getBody());
        pushRequest.setDeviceType(pushAdvancedDTO.getDeviceType());
        pushRequest.setPushType(pushAdvancedDTO.getPushType());
        pushRequest.setTarget(pushAdvancedDTO.getTarget());
        pushRequest.setTargetValue(pushAdvancedDTO.getTargetValue());
        pushRequest.setTitle(pushAdvancedDTO.getTitle());

//        DefaultAcsClient client =signConfig.sign();
        if (null != pushAdvancedDTO.getPushDate()) {
            pushRequest = timing(pushRequest, pushAdvancedDTO.getPushDate());
        }
        PushResponse pushResponse = null;
        try {
            pushResponse = sign.getAcsResponse(pushRequest);
        } catch (ClientException e) {
            log.info("context", e);
            return ResponseData.error("请求失败！Code：" + e.getErrCode() + ",Msg：" + e.getErrMsg());
        }
        return ResponseData.success(pushResponse);
    }

    @Override
    public ResponseData<ContinuouslyPushResponse> continuouslyPush(ContinuouslyPushDTO continuouslyPushDTO) {
        ContinuouslyPushRequest continuouslyPushRequest = new ContinuouslyPushRequest();
        continuouslyPushRequest.setAppKey(continuouslyPushDTO.getAppKey());
        // 设置持续推送的消息Id
        continuouslyPushRequest.setMessageId(continuouslyPushDTO.getMessageId().toString());
        // 指定推送目标
        // 可以继续用同一个`MessageId`，调用此接口指定其它设备，继续推送
        continuouslyPushRequest.setTarget(continuouslyPushDTO.getTarget());
        continuouslyPushRequest.setTargetValue(continuouslyPushDTO.getTargetValue());
//        DefaultAcsClient client =signConfig.sign();
        ContinuouslyPushResponse continuouslyPushResponse = null;
        try {
            continuouslyPushResponse = sign.getAcsResponse(continuouslyPushRequest);
        } catch (ClientException e) {
            log.info("context", e);
            return ResponseData.error("请求失败！Code：" + e.getErrCode() + ",Msg：" + e.getErrMsg());
        }
        return ResponseData.success(continuouslyPushResponse);
    }

    @Override
    public ResponseData<MassPushResponse> massPush(MassPushDTO massPushDTO) {
        MassPushRequest massPushRequest = new MassPushRequest();
        massPushRequest.setActionName("MassPush");
        massPushRequest.setAppKey(massPushDTO.getAppKey());
        List<MassPushRequest.PushTask> pushTasks = new ArrayList<>();
        for (int i = 0; i < massPushDTO.getAmount(); i++) {
            MassPushRequest.PushTask pushTask = new MassPushRequest.PushTask();
            // 推送目标
            pushTask.setTarget(massPushDTO.getPushTaskNTarget()); //推送目标: DEVICE:推送给设备; ACCOUNT:推送给指定帐号,TAG:推送给自定义标签; ALIAS: 按别名推送; ALL: 全推
            pushTask.setTargetValue(massPushDTO.getPushTaskNTargetValue()); //根据Target来设定，如Target=DEVICE, 则对应的值为 设备id1,设备id2. 多个值使用逗号分隔.(帐号与设备有一次最多100个的限制)
            pushTask.setDeviceType(massPushDTO.getPushTaskNDeviceType()); // 设备类型deviceType, iOS设备: "iOS"; Android设备: "ANDROID"; 全部: "ALL", 这是默认值.
            // 推送配置
            pushTask.setPushType(massPushDTO.getPushTaskNPushType()); // MESSAGE:表示消息(默认), NOTICE:表示通知
            pushTask.setTitle(massPushDTO.getPushTaskNTitle()); // 消息的标题
            pushTask.setBody(massPushDTO.getPushTaskNBody()); // 消息的内容
            pushTasks.add(pushTask);
        }
//        DefaultAcsClient client =signConfig.sign();
        massPushRequest.setPushTasks(pushTasks);
        MassPushResponse massPushResponse = null;
        try {
            massPushResponse = sign.getAcsResponse(massPushRequest);
        } catch (ClientException e) {
            log.info("context", e);
            return ResponseData.error("请求失败！Code：" + e.getErrCode() + ",Msg：" + e.getErrMsg());
        }
        return ResponseData.success(massPushResponse);
    }

    @Override
    public ResponseData<CancelPushResponse> cancelPush(CancelPushDTO cancelPushDTO) {
        CancelPushRequest cancelPushRequest = new CancelPushRequest();
        cancelPushRequest.setActionName("CancelPush");
        cancelPushRequest.setAppKey(cancelPushDTO.getAppKey());
        cancelPushRequest.setMessageId(cancelPushDTO.getMessageId());
//        DefaultAcsClient client =signConfig.sign();
        CancelPushResponse cancelPushResponse = null;
        try {
            cancelPushResponse = sign.getAcsResponse(cancelPushRequest);
        } catch (ClientException e) {
            log.info("context", e);
            return ResponseData.error("请求失败！Code：" + e.getErrCode() + ",Msg：" + e.getErrMsg());
        }
        return ResponseData.success(cancelPushResponse);
    }


    //定时推送控制
    public PushRequest timing(PushRequest pushRequest, String pushDate) {
//        Date pushDate = new Date(System.currentTimeMillis()) ; // 30秒之间的时间点, 也可以设置成你指定固定时间
        pushRequest.setPushTime(ParameterHelper.getISO8601Time(DateUtil.parse(pushDate))); // 延后推送。可选，如果不设置表示立即推送
        String expireTime = ParameterHelper.getISO8601Time(new Date(System.currentTimeMillis() + 12 * 3600 * 1000)); // 12小时后消息失效, 不会再发送
        pushRequest.setExpireTime(expireTime);
        return pushRequest;
    }

}
